﻿using System;
using System.Collections;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace SpyTxT
{  
    class NetClient
    {       
        private IPEndPoint ipep;
        private UdpClient udpc;
        private Thread recvthread;
        private Thread sendthread;
        private TcpClient tcpc;
        private IDoPack idopack;
        public enum NetMode{TCP_CLIENT,UDP_CLIENT};
        private ArrayList sendlist = new ArrayList();

        NetMode netmode;
        /*
         * 说明     :初始化网络,并且连接服务器
         * 
         * ip       :服务器IP
         * port     :服务器端口
         * dopack   :接收处理回调
         * netmode  :连接模式
         * 
         */
        public void InitNet(string ip, int port, IDoPack dopack, NetMode netmode)
        {
            
            this.idopack = dopack;
            this.netmode = netmode;
            ipep = new IPEndPoint(IPAddress.Parse(ip), port);
            if (netmode == NetMode.TCP_CLIENT)
            {
                tcpc = new TcpClient();
                tcpc.Connect(ipep);
            }
            else if (netmode == NetMode.UDP_CLIENT)
            {
                udpc = new UdpClient();
                udpc.Connect(ipep);
            }

            recvthread = new Thread(new ThreadStart(ClientRecvThread));
            recvthread.Start();

            sendthread = new Thread(new ThreadStart(ClientSendThread));
            sendthread.Start();


        }
        /*
         * 说明     :网络发送线程
         * 
         */
        private void ClientSendThread()
        {
           
            if (this.netmode == NetMode.TCP_CLIENT)
            {
                while (sendthread.IsAlive)
                {
                    if (sendlist.Count > 0)
                    {
                        Monitor.Enter(sendlist);

                        string data = (string)sendlist[0];

                        byte[] b = Encoding.Default.GetBytes(data);

                        if (tcpc.GetStream().CanWrite)
                        {
                            try
                            {
                                tcpc.GetStream().Write(b, 0, b.Length);

                                sendlist.RemoveAt(0);
                            }
                            catch (Exception e)
                            {
                                System.Diagnostics.Debug.WriteLine(e.Message);
                            }
                            finally
                            {

                            }

                        }
                        Monitor.Exit(sendlist);

                    }

                    Thread.Sleep(100);

                }
               

            }
            else if (this.netmode == NetMode.UDP_CLIENT)
            {
                while (sendthread.IsAlive)
                {
                    if (sendlist.Count > 0)
                    {
                        Monitor.Enter(sendlist);

                        string data = (string)sendlist[0];

                        byte[] b = Encoding.Default.GetBytes(data);

                        try
                        {
                            udpc.Send(b, b.Length);
                            sendlist.RemoveAt(0);
                        }
                        catch (Exception e)
                        {
                            System.Diagnostics.Debug.WriteLine(e.Message);
                        }
                        finally
                        {

                        }

                        Monitor.Exit(sendlist);

                    }
                    Thread.Sleep(100);

                }

                
            }
            
        }
        /*
         * 说明     : 网络接收线程
         * 
         */
        private void ClientRecvThread()
        {
            if (this.netmode == NetMode.TCP_CLIENT)
            {
                byte[] recvbuf = new byte[tcpc.ReceiveBufferSize];

                while (recvthread.IsAlive)
                {
                    if (tcpc.Connected && tcpc.GetStream().CanRead)
                    {
                        try
                        {
                            int readlen = tcpc.GetStream().Read(recvbuf, 0, (int)tcpc.ReceiveBufferSize);

                            idopack.IDoPackData(recvbuf, readlen);

                            Array.Clear(recvbuf, 0, recvbuf.Length); 

                            
                          

                        }
                        catch (Exception e)
                        {
                            System.Diagnostics.Debug.WriteLine(e.Message);

                        }
                    }

                }
            }
            else if(this.netmode == NetMode.UDP_CLIENT)
            {
                while (recvthread.IsAlive)
                {
                    try
                    {

                        Byte[] receiveBytes = udpc.Receive(ref ipep);

                        idopack.IDoPackData(receiveBytes, receiveBytes.Length);

                    }
                    catch (Exception e)
                    {
                        System.Diagnostics.Debug.WriteLine(e.Message);

                    }

                }
            }
        }
        /*
         * 说明     :发送数据
         * 
         */

        public void  ClientSend(string data)
        {
            Monitor.Enter(sendlist);

            sendlist.Add(data);

            Monitor.Exit(sendlist);
           
        }
        public void CloseClient()
        {
            if (this.netmode == NetMode.TCP_CLIENT && this.tcpc != null)
            {
                this.tcpc.Close();
            }
            else if (this.netmode == NetMode.UDP_CLIENT && udpc != null)
            {
                this.udpc.Close();
            }
            if(this.recvthread != null)
                this.recvthread.Abort();
            if(this.sendthread != null)
                this.sendthread.Abort();
        }
    
    }
}
